USE [QuanLyRapPhim]
GO
-- =============================================
-- Author:    DatNgo
-- Description: Đặt vé xem phim
-- =============================================
IF OBJECT_ID('sp_DatVe_fixed', 'P') IS NOT NULL
DROP PROC sp_DatVe_fixed
GO
CREATE PROCEDURE sp_DatVe_fixed
  @maHoaDon int,
  @maSuatChieu int,
  @maLoaiVe int,
  @maChoNgoi int
AS
BEGIN
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
  IF NOT EXISTS(SELECT 1 FROM HoaDon WHERE MaHoaDon=@maHoaDon) OR NOT EXISTS(SELECT 1 FROM SuatChieu WHERE MaSuatChieu=@maSuatChieu)
    OR NOT EXISTS(SELECT 1 FROM LoaiVe WHERE MaLoaiVe=@maLoaiVe) OR NOT EXISTS(SELECT 1 FROM ChoNgoi WHERE MaChoNgoi=@maChoNgoi)
  BEGIN
    print N'Tham số không hợp lệ'
    ROLLBACK TRAN
    RETURN
  END

  DECLARE @ngayDat datetime, @ngayThanhToan datetime
  SELECT @ngayDat=NgayDat, @ngayThanhToan=NgayThanhToan FROM HoaDon WHERE MaHoaDon=@maHoaDon
  IF @ngayThanhToan IS NOT NULL
  BEGIN
    print N'Hóa đơn đã được thanh toán, không thể đặt thêm vé'
    ROLLBACK TRAN
    RETURN
  END

  DECLARE @tgChieu datetime = (SELECT CAST(sc.NgayChieu AS datetime)+CAST(tg.ThoiGian AS time)
    FROM SuatChieu sc JOIN ThoiGianChieu tg ON tg.MaThoiGianChieu=sc.MaThoiGianChieu
    WHERE sc.MaSuatChieu=@maSuatChieu
  )
  DECLARE @tmpNgayDat datetime = DATEADD (day , 1 , @ngayDat)
  IF (@tmpNgayDat<@tgChieu OR @ngayDat>@tgChieu)
  BEGIN
    print N'Chỉ được đặt vé trước một ngày kể từ thời gian chiếu'
    ROLLBACK TRAN
    RETURN
  END

  IF EXISTS(SELECT 1 FROM Ve WITH(UPDLOCK) WHERE MaSuatChieu=@maSuatChieu AND MaChoNgoi=@maChoNgoi)
  BEGIN
    print N'Chỗ ngồi đã được đặt'
    ROLLBACK TRAN
    DELETE FROM Ve WHERE MaHoaDon=@maHoaDon
    DELETE FROM HoaDon WHERE MaHoaDon=@maHoaDon
    RETURN
  END
  WAITFOR DELAY '0:0:05'

  DECLARE @maVe int
  BEGIN TRY
    INSERT INTO Ve(MaSuatChieu, MaLoaiVe, MaChoNgoi, MaHoaDon)
    VALUES(@maSuatChieu, @maLoaiVe, @maChoNgoi, @maHoaDon)
    SET @maVe = SCOPE_IDENTITY()
    DECLARE @tongTien int, @giaVe int

    SELECT @tongTien=TongTien FROM HoaDon WITH(UPDLOCK) WHERE MaHoaDon=@maHoaDon
    SELECT @giaVe=Gia FROM LoaiVe WHERE MaLoaiVe=@maLoaiVe

    WAITFOR DELAY '0:0:05'

    SET @tongTien=@tongTien+@giaVe
    UPDATE HoaDon SET TongTien=@tongTien WHERE MaHoaDon=@maHoaDon
  END TRY
  BEGIN CATCH
    DECLARE @errMsg NVARCHAR(2000)
    SELECT @errMsg = N'Error: ' + ERROR_MESSAGE()
    RAISERROR(@errMsg, 16,1)
    ROLLBACK TRAN
    RETURN
  END CATCH

  PRINT N'Đặt vé thành công'
COMMIT TRAN
RETURN @maVe
END
GO

-- =============================================
-- Author:    DatNgo
-- Description: Đặt vé xem phim
-- =============================================
IF OBJECT_ID('sp_DatVe_TH1_fixed', 'P') IS NOT NULL
DROP PROC sp_DatVe_TH1_fixed
GO
CREATE PROCEDURE sp_DatVe_TH1_fixed
  @maHoaDon int,
  @maSuatChieu int,
  @maLoaiVe int,
  @maChoNgoi int
AS
BEGIN
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
  IF NOT EXISTS(SELECT 1 FROM HoaDon WHERE MaHoaDon=@maHoaDon) OR NOT EXISTS(SELECT 1 FROM SuatChieu WHERE MaSuatChieu=@maSuatChieu)
    OR NOT EXISTS(SELECT 1 FROM LoaiVe WHERE MaLoaiVe=@maLoaiVe) OR NOT EXISTS(SELECT 1 FROM ChoNgoi WHERE MaChoNgoi=@maChoNgoi)
  BEGIN
    print N'Tham số không hợp lệ'
    ROLLBACK TRAN
    DELETE FROM Ve WHERE MaHoaDon=@maHoaDon
    DELETE FROM HoaDon WHERE MaHoaDon=@maHoaDon
    RETURN
  END

  DECLARE @ngayDat datetime, @ngayThanhToan datetime
  SELECT @ngayDat=NgayDat, @ngayThanhToan=NgayThanhToan FROM HoaDon WHERE MaHoaDon=@maHoaDon
  IF @ngayThanhToan IS NOT NULL
  BEGIN
    print N'Hóa đơn đã được thanh toán, không thể đặt thêm vé'
    ROLLBACK TRAN
    DELETE FROM Ve WHERE MaHoaDon=@maHoaDon
    DELETE FROM HoaDon WHERE MaHoaDon=@maHoaDon
    RETURN
  END

  DECLARE @tgChieu datetime = (SELECT CAST(sc.NgayChieu AS datetime)+CAST(tg.ThoiGian AS time)
    FROM SuatChieu sc JOIN ThoiGianChieu tg ON tg.MaThoiGianChieu=sc.MaThoiGianChieu
    WHERE sc.MaSuatChieu=@maSuatChieu
  )
  DECLARE @tmpNgayDat datetime = DATEADD (day , 1 , @ngayDat)
  IF (@tmpNgayDat<@tgChieu OR @ngayDat>@tgChieu)
  BEGIN
    print N'Chỉ được đặt vé trước một ngày kể từ thời gian chiếu'
    ROLLBACK TRAN
    DELETE FROM Ve WHERE MaHoaDon=@maHoaDon
    DELETE FROM HoaDon WHERE MaHoaDon=@maHoaDon
    RETURN
  END

  IF EXISTS(SELECT 1 FROM Ve WITH(UPDLOCK) WHERE MaSuatChieu=@maSuatChieu AND MaChoNgoi=@maChoNgoi)
  BEGIN
    print N'Chỗ ngồi đã được đặt'
    ROLLBACK TRAN
    DELETE FROM Ve WHERE MaHoaDon=@maHoaDon
    DELETE FROM HoaDon WHERE MaHoaDon=@maHoaDon
    RETURN
  END
  WAITFOR DELAY '0:0:05'

  DECLARE @maVe int
  BEGIN TRY
    INSERT INTO Ve(MaSuatChieu, MaLoaiVe, MaChoNgoi, MaHoaDon)
    VALUES(@maSuatChieu, @maLoaiVe, @maChoNgoi, @maHoaDon)
    SET @maVe = SCOPE_IDENTITY()
    DECLARE @tongTien int, @giaVe int

    SELECT @tongTien=TongTien FROM HoaDon WITH(UPDLOCK) WHERE MaHoaDon=@maHoaDon
    SELECT @giaVe=Gia FROM LoaiVe WHERE MaLoaiVe=@maLoaiVe

    WAITFOR DELAY '0:0:05'

    SET @tongTien=@tongTien+@giaVe
    UPDATE HoaDon SET TongTien=@tongTien WHERE MaHoaDon=@maHoaDon
  END TRY
  BEGIN CATCH
    DECLARE @errMsg NVARCHAR(2000)
    SELECT @errMsg = N'Error: ' + ERROR_MESSAGE()
    RAISERROR(@errMsg, 16,1)
    ROLLBACK TRAN
    DELETE FROM Ve WHERE MaHoaDon=@maHoaDon
    DELETE FROM HoaDon WHERE MaHoaDon=@maHoaDon
    RETURN
  END CATCH

  PRINT N'Đặt vé thành công'
COMMIT TRAN
RETURN @maVe
END
GO

-- =============================================
-- Author:    DatNgo
-- Description: Hủy vé
-- =============================================
IF OBJECT_ID('sp_HuyVe_fixed', 'P') IS NOT NULL
DROP PROC sp_HuyVe_fixed
GO
CREATE PROCEDURE sp_HuyVe_fixed
  @maVe int
AS
BEGIN
BEGIN TRAN
  IF NOT EXISTS(SELECT 1 FROM Ve WITH (UPDLOCK) WHERE MaVe=@maVe)
  BEGIN
    print N'Vé không tồn tại'
    ROLLBACK TRAN
    RETURN
  END
  WAITFOR DELAY '0:0:05'

  BEGIN TRY
    DECLARE @maHoaDon int, @maLoaiVe int, @ngayThanhToan datetime, @tongTien int, @giaVe int;
    SELECT @maHoaDon=MaHoaDon, @maLoaiVe=MaLoaiVe FROM Ve WHERE MaVe=@maVe
    SELECT @ngayThanhToan=NgayThanhToan FROM HoaDon WHERE MaHoaDon=@maHoaDon

    IF @ngayThanhToan IS NOT NULL
    BEGIN
      print N'Hóa đơn đã được thanh toán, không thể hủy vé'
      ROLLBACK TRAN
      RETURN
    END
    SELECT @tongTien=TongTien FROM HoaDon WITH(UPDLOCK) WHERE MaHoaDon=@maHoaDon
    SELECT @giaVe=Gia FROM LoaiVe WHERE MaLoaiVe=@maLoaiVe

    WAITFOR DELAY '0:0:05'

    SET @tongTien=@tongTien-@giaVe
    UPDATE HoaDon SET TongTien=@tongTien WHERE MaHoaDon=@maHoaDon

    DELETE FROM Ve WHERE MaVe=@maVe
  END TRY
  BEGIN CATCH
    DECLARE @errMsg NVARCHAR(2000)
    SELECT @errMsg = N'Error: ' + ERROR_MESSAGE()
    RAISERROR(@errMsg, 16,1)
    ROLLBACK TRAN
    RETURN
  END CATCH

  PRINT N'Hủy vé thành công'
COMMIT TRAN
RETURN 1
END
GO

-- =============================================
-- Author:		DatNgo
-- Description: Thêm một suất chiếu cho phim
-- =============================================
IF OBJECT_ID('sp_ThemSuatChieu_fixed', 'P') IS NOT NULL
DROP PROC sp_ThemSuatChieu_fixed
GO
CREATE PROCEDURE sp_ThemSuatChieu_fixed
	@maPhim int,
	@maPhong int,
	@thoiGian time,
	@ngay date
AS
BEGIN
BEGIN TRAN
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
	IF NOT EXISTS(SELECT 1 FROM Phim WHERE MaPhim=@maPhim) OR NOT EXISTS(SELECT 1 FROM PhongChieu WHERE MaPhongChieu=@maPhong)
	BEGIN
		print N'Phim hoặc phòng chiếu ko tồn tại'
		ROLLBACK TRAN
		RETURN
	END

	WAITFOR DELAY '00:00:05'

	DECLARE @maThoiGian int;
	BEGIN TRY
		IF NOT EXISTS(SELECT 1 FROM ThoiGianChieu WHERE ThoiGian=@thoiGian)
		BEGIN
			INSERT INTO ThoiGianChieu(ThoiGian) VALUES(@thoiGian)
			SET @maThoiGian = SCOPE_IDENTITY()
		END
		ELSE
			SELECT @maThoiGian=MaThoiGianChieu FROM ThoiGianChieu WHERE ThoiGian=@thoiGian
		
		IF EXISTS (SELECT 1 FROM SuatChieu WITH(UPDLOCK) WHERE MaPhongChieu = @maPhong AND NgayChieu = @ngay AND MaThoiGianChieu = @maThoiGian)
		BEGIN
			print N'Phòng chiếu đã có lịch chiếu vào thời gian đó'
			ROLLBACK TRAN
			RETURN
		END
		INSERT INTO SuatChieu(MaPhim, MaPhongChieu, MaThoiGianChieu, NgayChieu)
		VALUES(@maPhim, @maPhong, @maThoiGian, @ngay)
	END TRY
	BEGIN CATCH
		DECLARE @errMsg NVARCHAR(2000)
		SELECT @errMsg = N'Error: ' + ERROR_MESSAGE()
		RAISERROR(@errMsg, 16,1)
		ROLLBACK TRAN
		RETURN
	END CATCH

	PRINT N'Thêm suất chiếu thành công'
COMMIT TRAN
RETURN 1
END
GO